#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <msg_queue_peer.h>
#include <errno.h>
#include "json.h"
#include "modbus.h"
#include <log_utils.h>
#include <list.h>
int sockfd;
static struct shm_param para;
static struct msgbuf recv_buf;
//static struct msgbuf send_buf;
unsigned char read_temp[128] = {0x02, 0xb7, 0x00, 0x00, 0x00, 0x06, 0x01, 0x04, 0x00, 0x00, 0x00, 0x02};
unsigned char read_hum[128] = {0x02, 0xb7, 0x00, 0x00, 0x00, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x02};
unsigned char read_air_temp[128] = {0x02, 0xb7, 0x00, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, 0x02};
unsigned char Air_ON[128] = {0x02, 0xb7, 0x00, 0x00, 0x00, 0x06, 0x01, 0x05, 0x00, 0x00, 0xFF, 0x00};
unsigned char Air_OFF[128] = {0x02, 0xb7, 0x00, 0x00, 0x00, 0x06, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00};
unsigned char LED_ON[128] = {0x02, 0xb7, 0x00, 0x00, 0x00, 0x06, 0x01, 0x05, 0x00, 0x01, 0xFF, 0x00};
unsigned char LED_OFF[128] = {0x02, 0xb7, 0x00, 0x00, 0x00, 0x06, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00};

void *send_thread(void *arg)
{
    struct std_node *mb_shm_addr = (struct std_node *)arg;
    int coil_data;             // 线圈
    float keep_data;           // 保持寄存器
    float input_data[2] = {0}; // 输入寄存器
    // int sockfd = *(int *)arg;
    while (1)
    {

        //  按照json中的键值读取
        //   temp_data=__func_03_temp(sockfd);
        //   mb_shm_addr->key=101;
        //   mb_shm_addr->new_val.f_val=temp_data;
        //   mb_shm_addr->ret=0;
        //   printf("温度=%.2f℃\n",mb_shm_addr->new_val.f_val);

        // hum_data=__func_03_hum(sockfd);
        // (mb_shm_addr+1)->key=102;
        // (mb_shm_addr+1)->new_val.f_val=hum_data;
        // (mb_shm_addr+1)->ret=0;
        // printf("湿度=%.2f%%\n",*(&(mb_shm_addr+1)->new_val.f_val));

        if (modbus_func_04(sockfd, input_data) < 0)
        {
            mb_shm_addr[0].ret = -1;
            mb_shm_addr[1].ret = -1;
            exit(-1);
        }
        for (int i = 0; i < 2; i++)
        {
            mb_shm_addr[i].ret = 0;
            mb_shm_addr[i].old_val.f_val = mb_shm_addr[i].new_val.f_val;
            mb_shm_addr[i].new_val.f_val = input_data[i];
        }
        printf("温度 = %0.2f℃,湿度 = %0.2f%%\n", input_data[0], input_data[1]);

        coil_data = modbus_func_01(sockfd);
        if (coil_data < 0)
        {

            mb_shm_addr[2].ret = -1;
            mb_shm_addr[4].ret = -1;
            exit(-1);
        }
        mb_shm_addr[2].ret = 0;
        mb_shm_addr[4].ret = 0;
        mb_shm_addr[2].old_val.b_val = mb_shm_addr[2].new_val.b_val;
        mb_shm_addr[4].old_val.b_val = mb_shm_addr[4].new_val.b_val;

        switch (coil_data) // 0：全关、1：空调开、2：灯开、3：全开
        {
        case 0:
            mb_shm_addr[2].new_val.b_val = 0;
            mb_shm_addr[4].new_val.b_val = 0;
            printf("空调OFF,灯OFF\n");
            break;
        case 1:
            mb_shm_addr[2].new_val.b_val = 1;
            mb_shm_addr[4].new_val.b_val = 0;
            printf("空调ON,灯OFF\n");
            break;
        case 2:
            mb_shm_addr[2].new_val.b_val = 0;
            mb_shm_addr[4].new_val.b_val = 1;
            printf("空调OFF,灯ON\n");
            break;
        case 3:
            mb_shm_addr[2].new_val.b_val = 1;
            mb_shm_addr[4].new_val.b_val = 1;
            printf("空调ON,灯ON\n");
            break;
        }
        keep_data = modbus_func_03(sockfd);
        if (keep_data < 0)
        {

            mb_shm_addr[3].ret = -1;
            exit(-1);
        }
        mb_shm_addr[3].ret = 0;
        mb_shm_addr[3].old_val.f_val = mb_shm_addr[3].new_val.f_val;
        mb_shm_addr[3].new_val.f_val = keep_data;
        printf("空调温度 = %.2f\n", keep_data);

        sleep(5);
        // pthread_exit(NULL);
    }
    // pause();
    // close(sockfd);
    //
}
void *recvthread(void *arg)
{

    cJSON *recv_root = NULL;
    cJSON *recv_data = NULL;
    cJSON *recv_key = NULL;
    cJSON *recv_val = NULL;

    int val = 0;
    // 判断消息队列存在
    while (msg_queue_msgexist("msg_modbus", 0))
    {
        msg_queue_recv("msg_modbus", &recv_buf, sizeof(recv_buf), 1, 0);
    }
    while (1)
    {
        if (msg_queue_recv("msg_modbus", &recv_buf, sizeof(recv_buf), 1, 0) > 0)
        {
            printf("recv type = %ld\n", recv_buf.mtype);
            printf("recv data = %s\n", recv_buf.mdata);
        }
        else
        {
            LOGE("recv data_report  error\n");
            break;
        }
        recv_root = cJSON_Parse(recv_buf.mdata);
        if (recv_root == NULL)
        {
            printf("error before: [%s]\n", cJSON_GetErrorPtr());
            return NULL;
        }
        unsigned char recv_buf_socket[128] = {0};
        recv_data = cJSON_GetObjectItem(recv_root, "data");
        recv_key = cJSON_GetObjectItem(recv_data, "key");
         recv_val = cJSON_GetObjectItem(recv_data, "val");
        val = atoi(cJSON_GetObjectItem(recv_data, "val")->valuestring);

        switch (recv_key->valueint)
        {
        case 101:
            send(sockfd, read_temp, 12, 0);
            break;
        case 102:
            send(sockfd, read_hum, 12, 0);

            break;
        case 103:
            if (val == 1)
            {
                send(sockfd, Air_ON, 12, 0);
            }
            else if (val == 0)
            {
                send(sockfd, Air_OFF, 12, 0);
            }
            break;
        case 104:

            if (modbus_func_16(sockfd, atof(recv_val->valuestring)) < 0)
            {
                printf("%s\n", recv_val->valuestring);
                LOGE("air set error!!!");
            }
            else
            {
                LOGD("air set success");
                printf("%lf\n", recv_val->valuedouble);
                printf("%d\n", recv_val->valueint);
            }
            break;
        case 105:
            if (val == 1)
            {
                send(sockfd, LED_ON, 12, 0);
            }
            else if (val == 0)
            {
                send(sockfd, LED_OFF, 12, 0);
            }
            break;
        }
        // 接收消息查看一下
        int ret = recv(sockfd, recv_buf_socket, 128, 0);
        if (ret < 0)
        {
            LOGE("recv data error");
            continue;
        }
        int i;
        for (i = 0; i < ret; i++)
        {
            // 将接收的内容打印出来看看
            printf("%02x ", recv_buf_socket[i]);
        }
        printf("\n");
        // 解析出需要的数据
        float *q = recv_buf_socket + 9; // 将指针偏移到数据位置
        // 小端存储
        float data;
        conver_endian_long(&data, q, 4);
       // LOGD("temp/hum data = %.2f\n", data);

        // 发送消息
        // 定义发送的消息序列化
        //     cJSON *root1 = cJSON_CreateObject();
        //     //发送给数据上报进程的消息序列化
        //    cJSON_AddItemToObject(root1, "type", cJSON_CreateNumber(2));
        //    cJSON_AddItemToObject(root1, "result", cJSON_CreateNumber(0));
        //    cJSON_AddItemToObject(root1, "msg", cJSON_CreateString("控制成功"));
        //    send_buf.mtype = 2;
        //    sprintf(send_buf.mdata, "%s", cJSON_Print(root1));
        //    printf("send=%s\n", send_buf.mdata);

        //     if (msg_queue_send("msg_report", &send_buf, sizeof(send_buf), 0) < 0)
        //     {
        //         LOGE("msg_queue_send error\n");
        //         return NULL;
        //     }
        // // pthread_exit(NULL);
        // //  cJSON_Delete(send_root);
        // // pause();
    }
    
    //pthread_exit(NULL);
}

int main(int argc, char const *argv[])
{
    set_dbg_level(APP_DEBUG);
    pthread_t tid1, tid2;

    char buf[2500] = {0};

    // 获取json文件
    int ret = read_json(buf);
    if (ret < 0)
    {
        LOGE("read node.json file error\n");
        return -1;
    }

    modbus_T *info = read_modbus_json_part(buf);
    if (info == NULL)
    {
        LOGE("port and ip get error");
        return -1;
    }

    if (shm_init(&para, "shm_modbus", 1024) < 0)
    {
        LOGE("get_mb_shm_addr error");
        return -1;
    }
    // 建立共享内存
    struct std_node *mb_shm_addr = shm_getaddr(&para);
    if (mb_shm_addr == NULL)
    {
        LOGE("shm_getaddr error ");
        return -1;
    }
    struct mb_node_list *mb_node = mb_node_list_init(buf, mb_shm_addr);
    if (mb_node == NULL)
    {
        LOGE("mb_node_list_init err");
        return -1;
    }

    // 连接
    sockfd = create_socket(info->ip, info->port);
    if (sockfd < 0)
    {
        LOGD("tcp connect error\n");
        return -1;
    }
    LOGI("-----------------------connect success----------------------------------");
    if (pthread_create(&tid1, NULL, send_thread, (void *)mb_shm_addr) != 0)
    {
        perror("pthread_create1 error");
        exit(-1);
    }
    LOGD("pthread_create1 success");

    if (pthread_create(&tid2, NULL, recvthread, NULL) != 0)
    {
        perror("pthread_create error");
        exit(-1);
    }
    LOGD("pthread_create2 success");

    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);
    close(sockfd);
    return 0;
}
